﻿using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Linq;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.DataServices;

namespace MvcForum.Hosting.Azure.Storage {

	public class AzureTableRepository<TEntity> : IDisposable where TEntity : TableServiceEntity {
		protected readonly CloudStorageAccount storageAccount;
		protected readonly TableServiceContext serviceContext;
		protected readonly String tableName;

		protected AzureTableRepository(String tableName)
			: this(tableName, DirectoryResolver.GetAccount()) {
		}

		protected AzureTableRepository(String tableName, CloudStorageAccount account) {
			this.storageAccount = account;
			this.tableName = tableName;

			CloudTableClient tableClient = this.storageAccount.CreateCloudTableClient();
			CloudTable table = tableClient.GetTableReference(tableName);
			table.CreateIfNotExists();
			this.serviceContext = tableClient.GetTableServiceContext();
		}

		public void Create<TEntity>(TEntity entity) {
			if (added > 0) {
				this.BulkSave();
			}
			this.serviceContext.AddObject(tableName, entity);
			this.serviceContext.SaveChangesWithRetries();
		}

		public IEnumerable<TEntity> GetPartitionContent(String partitionKey) {
			return this.serviceContext.CreateQuery<TEntity>(this.tableName).Where(e => e.PartitionKey == partitionKey).ToList();
		}

		private Int32 added = 0;
		public void BulkCreate<TEntity>(TEntity entity) {
			this.serviceContext.AddObject(tableName, entity);
			added++;
			if (added == 100) {
				this.BulkSave();
			}
		}

		private void BulkSave() {
			this.serviceContext.SaveChangesWithRetries(SaveChangesOptions.Batch);
			added = 0;
		}

		public void Dispose() {
			if (added > 0) {
				this.BulkSave();
			}
		}
	}
}